package com.gene.tlonpo.guard;

import java.util.List;
import java.util.Objects;
import java.util.concurrent.TimeUnit;

import com.gene.tlonpo.callback.CallBack;
import com.gene.tlonpo.guard.context.AsynContext;
import com.gene.tlonpo.guard.interf.GuardI;
import com.gene.tlonpo.guard.tool.GuardAggregationTool;
import com.gene.tlonpo.manager.EventManager;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;

/**
 * 哨兵请求信息
 * 给sdk使用方进行使用
 *
 * @author gene
 */
@Slf4j
@Data
public class GuardRequest implements GuardI {
    /**
     * 业务key
     * 监听的业务id
     */
    private String bizKey;

    /**
     * 超时时间
     * 默认10
     */
    private Long timeOut;

    /**
     * 超时时间单位
     * 默认秒
     */
    protected TimeUnit timeOutUnit;

    /**
     * callback
     * 事件处理callback
     * 接收事件之后的业务处理callback
     */
    private CallBack callBack;

    /**
     * callback的入餐
     */
    private Object callBackReq;

    /**
     * 关心的事件
     * 如果本实例没有注册生效事件，此处赋值将不生效
     */
    private List<String> guardEventList;

    /**
     * 异步上下文
     * 用于异步处理写回数据
     */
    private AsynContext asynContext;

    /**
     * 开启哨兵
     * 提供给使用方调用
     */
    public void open() {
        GuardAggregationTool.addGuard(this);
    }

    /**
     * 数据校验
     */
    public void selfValidate() {
        if (StringUtils.isEmpty(this.bizKey)) {
            throw new RuntimeException("can not open guard,because of the proper bizKey is empty");
        }

        if (Objects.isNull(this.timeOut)) {
            log.warn("open guard,the proper timeOut is null,use default value 10");
            this.timeOut = 10L;
        }

        if (Objects.isNull(this.timeOutUnit)) {
            log.warn("open guard,the proper timeOutUnit is null,use default value SECONDS");
            this.timeOutUnit = TimeUnit.SECONDS;
        }

        if (Objects.isNull(this.callBack)) {
            throw new RuntimeException("can not open guard,because of the proper callBack is not instance");
        }

        //上下文
        if (Objects.isNull(this.asynContext)) {
            throw new RuntimeException("can not open guard,because of the proper asynContext is not instance");
        }

        //关心的事件，如果开启了事件管理，则必须有值，如果未开启事件管理，此属性值会被忽略
        if (EventManager.isSupport() && CollectionUtils.isEmpty(this.guardEventList)) {
            throw new RuntimeException(
                "can not open guard,because of the proper guardEventList is empty,you can add event or close event "
                    + "manager");
        }

    }

}
